/*
 *    Copyright (c) 2018-2025, nart All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: nart
 */
package com.nai365.nart.member.service.impl;

import cn.hutool.core.codec.Rot;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nai365.nart.common.core.constant.SecurityConstants;
import com.nai365.nart.common.core.util.R;
import com.nai365.nart.common.core.vo.WalletChangeVo;
import com.nai365.nart.member.config.RabbitmqConfig;
import com.nai365.nart.member.dto.*;
import com.nai365.nart.member.entity.Member;
import com.nai365.nart.member.entity.Wallet;
import com.nai365.nart.member.feign.WalletRemoteService;
import com.nai365.nart.member.mapper.MemberMapper;
import com.nai365.nart.member.service.MemberService;
import com.nai365.nart.order.api.feign.OrderFeignService;
import com.nai365.nart.order.entity.Order;
import com.nai365.nart.order.entity.OrderItem;
import com.nai365.nart.product.api.feign.RemoteSkuService;
import com.nai365.nart.product.entity.SkuInfo;
import lombok.AllArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 会员
 *
 * @author baogs
 * @date 2022-07-01 10:52:57
 */
@AllArgsConstructor
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

	private final OrderFeignService orderFeignService;

	//private final WalletChangeRemoteService walletChangeRemoteService;

	private final WalletRemoteService walletRemoteService;

	private final RemoteSkuService remoteSkuService;


	private final RabbitTemplate rabbitTemplate;




	@Override
	public Member findMemberByPhone(String phone) {

		LambdaQueryWrapper<Member> memberLambdaQueryWrapper = new LambdaQueryWrapper<>();
		memberLambdaQueryWrapper.eq(Member::getMobile, phone);

		Member member = this.getOne(memberLambdaQueryWrapper);
		return member;
	}

	@Override
	public Object updateMemberIsVerify(ChainVerifyUserDto chainVerifyUserDto) {


		LambdaUpdateWrapper<Member> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
		lambdaUpdateWrapper
				.eq(Member::getUserId, chainVerifyUserDto.getUserId())
				.set(Member::getIsVerify, chainVerifyUserDto.getIsVerify())
				.set(Member::getRealName, chainVerifyUserDto.getRealName())
				.set(Member::getOpbChainClientAddress, chainVerifyUserDto.getChainAdress());

//		UpdateWrapper<Member> updateWrapper = new UpdateWrapper<>();
//		updateWrapper
//				.eq("user_id",chainVerifyUserDto.getUserId())
//				.set("is_verify",chainVerifyUserDto.getIsVerify())
//				.set("real_name",chainVerifyUserDto.getRealName())
//				.set("opb_chain_client_address",chainVerifyUserDto.getChainAdress());

		return this.update(lambdaUpdateWrapper);
	}

	@Override
	public List<SimpleMemberDto> findByIds(Collection<Serializable> ids) {
		if (ObjectUtils.isEmpty(ids)) {
			return new ArrayList<>();
		}
		return this.listByIds(ids).stream().map(member -> {
			SimpleMemberDto simpleMemberDto = new SimpleMemberDto();
			BeanUtils.copyProperties(member, simpleMemberDto);
			return simpleMemberDto;
		}).collect(Collectors.toList());
	}

	@Override
	public Boolean setPayPass(PayPassDto payPassDto) {
		LambdaUpdateWrapper<Member> lambdaUpdateWrapper = new LambdaUpdateWrapper<Member>()
				.set(Member::getPayPass, Rot.encode13(payPassDto.getPayPass()))
				.eq(Member::getUserId, payPassDto.getUserId());
		return this.update(lambdaUpdateWrapper);
	}


	private Boolean payVerifyPass(RemainderDto remainderDto) {
		LambdaQueryWrapper<Member> memberLambdaQueryWrapper = new LambdaQueryWrapper<>();
		memberLambdaQueryWrapper.eq(Member::getUserId, remainderDto.getUserId());
		Member member = this.getOne(memberLambdaQueryWrapper);
		return Rot.encode13(remainderDto.getPayPass()).equals(member.getPayPass());
	}

	@Override
	public R<Boolean> payByRemainder(RemainderDto remainderDto) {
		//比较密码
		if (!this.payVerifyPass(remainderDto)) {
			return R.failed(Boolean.FALSE, "支付密码错误!");
		}
		//对比余额
		R<Order> res = orderFeignService.findOrderByOrderId(remainderDto.getOrderSn(), SecurityConstants.FROM_IN);
		Order order = res.getData();
		Wallet walletByUserId = walletRemoteService.findWalletByUserId(remainderDto.getUserId(), SecurityConstants.FROM_IN);
		BigDecimal totalAmount = order.getTotalAmount();
		//钱包余额
		BigDecimal rmbBalance = walletByUserId.getRmbBalance();
		//BigDecimal rmbValue = walletChange.getRmbValue();
		if (rmbBalance.compareTo(totalAmount) == -1) {
			return R.failed(Boolean.FALSE, "订单已支付! 或已失效！");
		}

		if (order.getStatus() != 0) {
			return R.failed(Boolean.FALSE, "余额不足!");
		}
		//正常下单 改变钱包里面的余额
		WalletChangeVo walletChangeVo = new WalletChangeVo();
		walletChangeVo.setFromUserId(order.getMemberId());
		walletChangeVo.setToUserId(order.getMemberId());
		walletChangeVo.setOrderSn(order.getOrderSn());
		walletChangeVo.setRmbValue(totalAmount.negate());
		walletChangeVo.setType(order.getOrderType());
		walletChangeVo.setSkuName(remainderDto.getSpuName());
		//walletChangeVo.setCurrentBalance(rmbBalance.add());

		R r = walletRemoteService.updateByIdInner(walletChangeVo, SecurityConstants.FROM_IN);

		//修改订单状态
		orderFeignService.modifyOrderStatus(order.getOrderSn(), 3, SecurityConstants.FROM_IN);


		TransferDto transferDto = new TransferDto();
		transferDto.setCopies(1);
		Member byId = this.getById(order.getOwnId());
		transferDto.setFrom(byId.getOpbChainClientAddress());

		transferDto.setRequestId(UUID.randomUUID().toString().replace("-", ""));
		transferDto.setNotifyRoute("chian");
		transferDto.setExchangeName("chianQueueExchange");
		//
		Member member = this.getById(order.getMemberId());
		transferDto.setTo(member.getOpbChainClientAddress());
		//获取token 订单id
		//Long id = order.getId();
		OrderItem orderItemByOrderId = orderFeignService.findOrderItemByOrderId(order.getId(), SecurityConstants.FROM_IN);
		//OrderItem orderItemByOrderId = orderFeignService.findOrderItemByOrderId(Long.valueOf(order.getOrderSn()));
		//根据item项的spuid 查询 token
		Long skuId = orderItemByOrderId.getSkuId();
		SkuInfo skuInfo = remoteSkuService.findSkuInfoBySkuId(skuId, SecurityConstants.FROM_IN);
		transferDto.setToken(skuInfo.getToken().toString());

		transferDto.setRequestId(order.getOrderType() + "-" + skuId.toString() + "-" + member.getId());
		rabbitTemplate.convertAndSend(RabbitmqConfig.BLOCKCHAIN_EXCHANGE, RabbitmqConfig.TRANSFER_ROUTING_KEY, transferDto);


		return R.ok(Boolean.TRUE, "支付成功！");
	}

	@Override
	public Member findCoinAdress(Long merberId) {

		return this.getById(merberId);
	}
}
